package app.caihan.scframe.base.activity

import android.os.Bundle
import androidx.annotation.MainThread
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import app.caihan.scframe.base.viewmodel.BaseViewModel
import app.caihan.scframe.common.loadinghelper.LoadingHelper
import app.caihan.scframe.common.loadinghelper.ToolbarConfig
import app.caihan.scframe.common.loadinghelper.ToolbarType
import app.caihan.scframe.common.loadinghelper.ToolbarUtils
import app.caihan.scframe.constant.DEBUG_TAG
import app.caihan.scframe.ktx.getVmClazz
import app.caihan.scframe.util.CoroutineState
import app.caihan.scframe.util.NetworkStateManager
import com.blankj.utilcode.util.LogUtils

/**
 * ViewModelActivity基类
 *
 * @author Seven-C
 * @date 2020/7/27
 */
abstract class BaseVmActivity<VM : BaseViewModel> : BaseActivity(), IBaseVmActivity {


    /**
     * 是否使用默认导航布局
     */
    private val toolbarConfig by lazy { useBaseToolbar() }

    /**
     * 是否需要使用DataBinding 供子类BaseVmDbActivity修改，用户请慎动
     */
    private val isUseDb by lazy { useDataBinding() }

    val mViewModel: VM by lazy { createViewModel() }

    private val mActivityProvider by lazy { ViewModelProvider(this) }

    protected lateinit var loadingHelper: LoadingHelper

    /**
     * 默认导航布局返回键自定义处理
     */
    protected open fun onNavBackClick() {

    }


    /**
     * 是否需要使用DataBinding 供子类BaseVmDbActivity修改
     * @return [isUseDb]
     */
    protected open fun useDataBinding(): Boolean {
        return false
    }

    /**
     * 是否需要使用默认的导航布局
     * @return [toolbarConfig]
     */
    protected open fun useBaseToolbar(): ToolbarConfig {
        return ToolbarConfig()
    }

    /**
     * 在BaseActivity onCreate后调用
     */
    override fun setContentView(savedInstanceState: Bundle?) {
        if (!isUseDb) {
            super.setContentView(bindLayoutId())
        } else {
            initDataBind()
        }
        init(savedInstanceState)
    }

    /**
     * 初始化LoadingHelper,
     * BaseVmActivity onCreate->setContentView-> init(savedInstanceState: Bundle?)中调用
     * 在DataBinding需要使用LoadingHelper(mBinding.root)
     */
    protected open fun initLoadingHelper() {
        loadingHelper = LoadingHelper(this)
    }

    /**
     * 初始化DataBinding
     */
    @MainThread
    protected open fun initDataBind() {
    }

    /**
     * 在BaseVmActivity onCreate->setContentView后调用
     */
    private fun init(savedInstanceState: Bundle?) {
        initLoadingHelper()
        initView(savedInstanceState)
        if (toolbarConfig.isUseBaseToolbar) {
            setBaseToolbar()
        } else {
            setStatusBarStyle()
        }
        registerUiChange()
        createObserver()
        //监听网络变化
        lifecycle.addObserver(NetworkStateManager.instance)
        NetworkStateManager.instance.networkState.observeInActivity(this, Observer {
            onNetworkStateChanged(it)
        })
    }

    /**
     * 重载页面,在loadingHelper的ErrorAdapter布局中调用
     */
    protected open fun onReload() {}

    /**
     * 绑定默认导航布局
     */
    private fun setBaseToolbar() {
        when (toolbarConfig.type) {
            ToolbarType.APPBAR -> ToolbarUtils.setBaseToolbarAdapter(loadingHelper, toolbarConfig)
            ToolbarType.TOOLBAR -> ToolbarUtils.setToolbar(loadingHelper, toolbarConfig)
        }
    }

    /**
     * 创建viewModel
     */
    private fun createViewModel(): VM {
        //注意 type.actualTypeArguments[0]=BaseViewModel
//        val type = javaClass.genericSuperclass as ParameterizedType
//        val vmClass = type.actualTypeArguments[0] as Class<VM>
        return mActivityProvider.get(getVmClazz(this, 0))
    }

    /**
     * 注册 UI 事件
     */
    protected open fun registerUiChange() {
        mViewModel.statusLiveData.observe(this, Observer {
            LogUtils.dTag(DEBUG_TAG, "registerUiChange statusLiveData $${it.state}")
            when (it.state) {
                CoroutineState.FINISH.state -> loadingHelper.showContentView()
                CoroutineState.START.state -> loadingHelper.showLoadingView()
                CoroutineState.REFRESH.state -> loadingHelper.showLoadingView()
                CoroutineState.ERROR.state -> loadingHelper.showErrorView()
            }
        })
        mViewModel.errorLiveData.observe(this, Observer {
            LogUtils.dTag(DEBUG_TAG, "registerUiChange errorLiveData $${it.errMsg}")
            loadingHelper.setErrorAdapterMsg(it.errMsg)
        })
    }

    /**
     * 网络变化监听 子类重写
     */
    protected open fun onNetworkStateChanged(netState: Boolean) {}


}